package 排序;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;

/**
 * @author admin
 * @version 1.0.0
 * @ClassName 数组中最强的k个值.java
 * @Description TODO
 * @createTime 2020年11月18日 08:32:00
 * 给你一个整数数组 arr 和一个整数 k 。
 *
 * 设 m 为数组的中位数，只要满足下述两个前提之一，就可以判定 arr[i] 的值比 arr[j] 的值更强：
 *
 *  |arr[i] - m| > |arr[j] - m|
 *  |arr[i] - m| == |arr[j] - m|，且 arr[i] > arr[j]
 * 请返回由数组中最强的 k 个值组成的列表。答案可以以 任意顺序 返回。
 *
 * 中位数 是一个有序整数列表中处于中间位置的值。形式上，如果列表的长度为 n ，那么中位数就是该有序列表（下标从 0 开始）中位于 ((n - 1) / 2) 的元素。
 *
 * 例如 arr = [6, -3, 7, 2, 11]，n = 5：数组排序后得到 arr = [-3, 2, 6, 7, 11] ，数组的中间位置为 m = ((5 - 1) / 2) = 2 ，中位数 arr[m] 的值为 6 。
 * 例如 arr = [-7, 22, 17, 3]，n = 4：数组排序后得到 arr = [-7, 3, 17, 22] ，数组的中间位置为 m = ((4 - 1) / 2) = 1 ，中位数 arr[m] 的值为 3 。
 *  
 *
 * 示例 1：
 *
 * 输入：arr = [1,2,3,4,5], k = 2
 * 输出：[5,1]
 * 解释：中位数为 3，按从强到弱顺序排序后，数组变为 [5,1,4,2,3]。最强的两个元素是 [5, 1]。[1, 5] 也是正确答案。
 * 注意，尽管 |5 - 3| == |1 - 3| ，但是 5 比 1 更强，因为 5 > 1 。
 *
 */
public class 数组中最强的k个值 {
    public static void main(String[] args) {
        Solution solution=new Solution();
        int[] strongest = solution.getStrongest(new int[]{6,-3,7,2,11}, 3);
        System.out.println(Arrays.toString(strongest));
    }

    static class Solution {
        //排序+双指针
        public int[] getStrongest(int[] arr, int k) {
            Arrays.sort(arr); // 将数组按数值从小到大排序
            int mid = arr[(arr.length - 1) / 2],index = 0;
            // mid为数组的中位数，注意题目中定义的中位数与“一般定义”不同
            int[] ans = new int[k];
            int left = 0,right = arr.length - 1;
            while(index < k) { // 直到获取k个数为止
                int a = Math.abs(arr[left] - mid),b = Math.abs(arr[right] - mid);
                /* 按规则获取数字 */
                if(a > b) {
                    ans[index] = arr[left];left++;index++;
                }
                else { // 由于数组中的数字按升序排序，因此右边的数总是大于左边的
                    ans[index] = arr[right];right--;index++;
                }
            }
            return ans;
        }
    }



    class Solution2 {

        public int[] getStrongest(int[] arr, int k) {
            //双指针 分别指向两个数组
            //排序+双指针
            Arrays.sort(arr); // 将数组按数值从小到大排序
            int mid = arr[(arr.length - 1) / 2],index = 0;
            // mid为数组的中位数，注意题目中定义的中位数与“一般定义”不同
            int[] ans = new int[k];
            int left = 0,right = arr.length - 1;
            while(index < k) { // 直到获取k个数为止
                int a = Math.abs(arr[left] - mid),b = Math.abs(arr[right] - mid);
                /* 按规则获取数字 */
                if(a > b) {
                    ans[index] = arr[left];left++;index++;
                }
                else { // 由于数组中的数字按升序排序，因此右边的数总是大于左边的
                    ans[index] = arr[right];right--;index++;
                }
            }
            return ans;
        }
    }


}
